#include "timer.h"

#include <Windows.h>
#include <mmsystem.h>
#pragma comment(lib,"Winmm.lib")

#include <chrono>
#include <thread>
#include <iostream>


static std::chrono::high_resolution_clock::time_point start;



void CALLBACK OnTimer(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) {
    Timer* pTimer = (Timer*)(dwUser);
    pTimer->onTimer();
}

static uint32_t innerTimerIDl;


Timer::Timer(uint32_t tickMs, uint32_t wheelSize)
{
    innerTimerIDl = timeSetEvent(tickMs, 0, (LPTIMECALLBACK)OnTimer, (DWORD_PTR)this, TIME_PERIODIC);
    TimerNodeVec.resize(wheelSize);
}

Timer::~Timer()
{
    timeKillEvent(innerTimerIDl);
}

uint32_t Timer::Creat(uint32_t ms, std::function<void(uint32_t id, std::shared_ptr<void>)> callback, std::shared_ptr<void> userdata)
{
    auto execTime = ms + ticks;
    auto tt = m_tickMs * m_wheelSize;  // 一轮时间
    auto level = ms / tt;
    auto cnt = ms % tt;


    auto pNnode = std::make_shared<TimerNode>();
    pNnode->id = 1;
    pNnode->repeat = true;
    pNnode->cancel = false;
    pNnode->userdata = userdata;
    pNnode->interval = ms;
    pNnode->circle = level;
    pNnode->callback = callback;

    TimerNodeVec[cnt].emplace_back(pNnode);
}

void Timer::StopOne(uint32_t id)
{
}

// 终止定时器
void Timer::StopAll()
{

}

void Timer::onTimer()
{
    ++ticks;
    if (ticks == m_wheelSize) {
        ticks.store(0);
    }
    checkTimer(ticks.load());
}

void Timer::checkTimer(uint32_t i)
{
    if (!TimerNodeVec[i].empty()) {

        std::vector<std::shared_ptr<TimerNode>> toRemove;

        for (auto& node : TimerNodeVec[i]) {
            if (node->cancel) {
                continue;
            }

            if (node->circle == 0) {
                node->callback(node->id, node->userdata);

                if (node->repeat) {
                    // 添加到新格子
                }
            }
            else {
                --node->circle;
            }
        }
    }
}
